home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_c
/
mikecom
/
async.doc
< prev
next >
Wrap
Text File
|
1987-05-19
|
20KB
|
423 lines
*******************************************************************************
ASYNC FUNCTIONS FOR MICROSOFT C
Mike Dumdei, 6 Holly Lane, Texarkana TX 75503
*******************************************************************************
These functions provide a library of interrupt driven communications routines
for users of MicroSoft C versions 3 and 4. They make calls to the MSC library
functions 'malloc' and 'free' so if you want to modify them to work with a
compiler other than MicroSoft's you will need to use your compiler's version
of these functions. The ASYNC.H header file sets up most of the segment names
which should make conversion easier if you want to attempt it.
The routines support all memory models (small, compact, medium, large, and
huge) and a library for any size model can be created using the included
MAKE file 'A_LIB.NEW' and defining the model size desired. Ex:
make size=LARGE a_lib.new
If a memory size is not given a SMALL lib is the default. If you are not
using make, you can assemble for different sizes using MASM by defining the
memory model on the command line. Ex:
masm async /dLARGE /mx;
COMM.H is an include file that contains the function decalarations and various
definitions that apply to the ASYNC routines.
DESCRIPTION OF FUNCTIONS:
-------------------------------------------------------------------------------
ASYNC_CARRIER -- fast check for carrier detect present.
-------------------------------------------------------------------------------
Example:
int async_carrier(int);
rcode = async_carrier(port);
Returns:
TRUE (1) - carrier was present
FALSE (0) - no carrier detected
R_NOPORT - the port hasn't been opened
To monitor carrier detect while transmitting, use this function to get the
fastest executing code. When receiving, for the fastest code, check the CD
bit in the STAT1 byte which is returned with the character. Async_stat also
returns carrier detect status but is slightly slower than either of the above
since it also gets some other information. TRUE and FALSE are not defined
in COMM.H.
-------------------------------------------------------------------------------
ASYNC_CLOSE -- close a serial communications port.
-------------------------------------------------------------------------------
Example:
int async_close(int);
rcode = async_close(port);
Returns:
R_OK - close was successful
R_NOPORT - the port hasn't been opened
This function closes an opened port. All data in the buffers is lost. The
modem registers and the interrupt controller are returned to the state they
were in when the port was opened. This function makes a call to the MSC
library function 'FREE'.
-------------------------------------------------------------------------------
ASYNC_DTR -- toggle DTR modem signal.
-------------------------------------------------------------------------------
Example:
int async_dtr(int, int);
rcode = async_dtr(port, flag);
Returns:
R_OK - operation was successful
R_NOPORT - the port hasn't been opened
A zero flag will cause the modem signal 'Data Terminal Ready' to be brought
to its FALSE state. Often used to hang up the modem. A non-zero flag
re-enables the DTR signal. The DTR signal is set to the TRUE condition when
a port is first opened.
-------------------------------------------------------------------------------
ASYNC_MSR -- get the value of the modem status register.
-------------------------------------------------------------------------------
Example:
int async_msr(int);
msr_val = async_msr(port);
Returns:
High byte = 0, low byte equals current contents of the MSR.
R_NOPORT - the port hasn't been opened
This function does not actually read the modem status register. That is done
using the modem status interrupt function of the comm chip. When a modem
status interrrupt occurs the MSR is read and the value placed in a storage
area. This function returns the value from the storage area.
-------------------------------------------------------------------------------
ASYNC_MSRFLOW -- set the mask for modem signals to be monitored while tx'ing.
-------------------------------------------------------------------------------
Example:
int async_msrflow(int, int);
rcode = async_msrflow(port, mask);
Returns:
R_OK - operation was successful
R_BADARG - attempted to set bits in mask other than CTS, DSR, or CD
R_NOPORT - the port hasn't been opened
Use this function to set the bit mask for the modem status signals that must be
in the TRUE state for transmit interrupts to be active. Signals that can be
monitored are Clear to Send, Data Set Ready, and Carrier Detect. To set the
mask for CTS handshaking you would - async_msrflow(COM1, B_CTS);
where COM1 == 1 and B_CTS == 0x0010. These are defined in COMM.H.
Be careful when monitoring the CD bit. If you set the bit to monitor this
signal and a carrier is not present all bytes transmitted will go to the tx
buffer and no further (this includes modem dial commands, etc). If you want to
stop transmitting if CD is lost set the bit after CD is in its TRUE state.
-------------------------------------------------------------------------------
ASYNC_OPEN -- open a serial communications port.
-------------------------------------------------------------------------------
Example:
int async_open(int, char *, int, int);
rcode = async_open(port, "2400N81", txbuf_size, rxbuf_size);
Returns:
R_OK - the operation was successful
R_NOPORT - the port is shown as non-existent in the BIOS data area
R_BAUDERR - attempted to set the baud rate higher than 19.2K
R_PARITYERR - parity indicator in BPDS string wasn't E, O, or N
R_DTABITERR - data bits were not either 7 or 8
R_STPBITERR - stop bits were not either 1 or 2
R_PORTINUSE - attempted to open an already opened port
R_BADARG - requested bufr size outside limits or invalid BPDS string
R_NOMEM - internal call to MSC's 'malloc' function failed
Currently async_open supports COM1 - COM2 so in the example port must be either
1 or 2. The string, Baud Parity Data Stop (BPDS string), is used to set the
line parameters. The size of the transmit and receive buffers is dynamically
allocated by a call to the MSC library's MALLOC function. The maximum size for
either buffer is 32000 bytes and the minimum size is 100 for the tx buffer and
750 for the rx buffer.
-------------------------------------------------------------------------------
ASYNC_RESET -- resets rx error bits in STAT1 byte.
-------------------------------------------------------------------------------
Example:
int async_reset(int);
rcode = async_reset(port);
Returns:
R_OK - operation was successful
R_NOPORT - the port hasn't been opened
This function resets any rx error conditions that are signaled in the STAT1
byte. It is the only way to clear the error bits once they are set. See
async_rx for more information on STAT1.
-------------------------------------------------------------------------------
ASYNC_RTS -- toggle RTS modem signal.
-------------------------------------------------------------------------------
Example:
int async_rts(int, int);
rcode = async_rts(port, flag);
Returns:
R_OK - operation was successful
R_NOPORT - the port hasn't been opened
A zero flag will cause the modem signal 'Request to Send' to be brought
to its FALSE state. This signal is used for handshaking. A non-zero flag
re-enables the RTS signal. When a port is first opened the RTS signal will
be set TRUE unless RTSFALSE was defined on the command line when assembling
the ASYNC.ASM module. The MAKE files included in the ARC do not make that
definition so if you use it RTS will initially be TRUE.
-------------------------------------------------------------------------------
ASYNC_RX -- get a character from the receive buffer.
-------------------------------------------------------------------------------
Example:
int async_rx(int);
stat_and_char = async_rx(port);
Returns:
Low byte is character read and high byte is STAT1.
STAT1: 0=rx bufr ovrfl 1=char overrun 2=parity err 3=framing err
4=break intrpt 5=invalid port 6=rx bufr empty 7=no carrier
STAT1 was designed so that it would be equal to 0 if no line type errors have
been detected, the buffer had something in it, and a carrier is present. If
a call is made to async_rx when the buffer has nothing in it a '\0' will be
returned as the character and bit 6 will be set in STAT1. Bit 0 of STAT1
will be set if the rx buffer has overflowed. Bits 1 thru 4 indicate a line
error or a break signal was received on the comm port. Bit 5 indicates the
comm port hadn't been opened and bit 7 that the carrier has been lost.
The conditions reflected in bits 0-4 indicate that an error of that type has
occurred since the port was opened or since async_reset was called. Since
the receive is buffered the char read when STAT1 first indicates the condition
is not necessarily the char that triggered the condition. Once bits 0-4 are
set they remain set until async_reset is called.
The STAT1 byte can be ignored by casting the returned value to the char type.
-------------------------------------------------------------------------------
ASYNC_RXCNT -- get the number of bytes of unprocessed data in the rx buffer.
-------------------------------------------------------------------------------
Example:
int async_rxcnt(int);
chars_to_read = async_rxcnt(port);
Returns:
Number of bytes in the rx buffer that have not been read if successful.
R_NOPORT - the port hasn't been opened
The R_NOPORT return value is a negative number and a successful return is
always positive so you can't mistakenly interpret an error return as the number
of bytes in the buffer. Also as long as the port has been opened the error
return will never occur anyway.
-------------------------------------------------------------------------------
ASYNC_RXFLUSH -- flush the receive buffer.
-------------------------------------------------------------------------------
Example:
int async_rxflush(int);
rcode = async_rxflush(port);
Returns:
R_OK - operation was successful
R_NOPORT - the port hasn't been opened
-------------------------------------------------------------------------------
ASYNC_SETBPDS -- set baud, parity, # data bits, # stop bits.
-------------------------------------------------------------------------------
Example:
int async_setbpds(int, char *);
rcode = async_setbpds(port, bpds_string);
Returns:
R_OK - operation was successful
R_NOPORT - the port hasn't been opened
R_BAUDERR - attempted to set the baud rate higher than 19.2K
R_PARITYERR - parity indicator in BPDS string wasn't E, O, or N
R_DTABITERR - data bits were not either 7 or 8
R_STPBITERR - stop bits were not either 1 or 2
R_BADARG - extra characters in BPDS string
This function changes the line parameters of an already opened comm port. This
function also changes the STRIP_MASK to no high bit stripping if the number
of data bits is set to 8 (see async_strip for more on the STRIP_MASK). Mark
parity, and less than 7 data bits are not supported. The baud rate may be
set to any value between 1 and 19200 baud.
The BPDS string has the form "2400N81", "1200E71", "19200N81", "733N72", etc.
First is the baud rate desired, then E O or N for type of parity, followed by
the number of data bits, and last the number of stop bits.
-------------------------------------------------------------------------------
ASYNC_STAT -- get port status information.
-------------------------------------------------------------------------------
Example:
int async_stat(int, int);
status = async_stat(port, status_mask);
Returns:
STAT1 - high byte, STAT2 - low byte if successful
R_NOPORT - the port hasn't been opened
STAT1: 0=rx bufr ovrfl 1=char overrun 2=parity err 3=framing err
4=break intrpt 5=not used 6=rx bufr empty 7=no carrier
STAT2: 0=XON/OFF in use 1=XOFF received 2=XOFF sent 3=tx buf empty
4=montr'g CTS 5=montr'g DSR 6=flw hlt actv 7=montr'g CD
Information contained in the STAT1 byte is described in async_rx section.
There is one difference which is bit 5 is not used by this function to indi-
cate an invalid port as it is in async_rx. Bits 0 - 2 of STAT2 return infor-
mation on XON/OFF protocol status. Bit 3 - the transmit buffer is empty,
bits 4, 5, & 7 - tell which signals the transmit interrupt routine is watching
and will shut down if they go false (set by async_msrflow), bit 6 - indicates
that either XON/OFF protocol is being used and an XOFF was received or one
of the monitored modem signals has gone to the low state.
The status mask passed in the function is anded with STAT1;STAT2 information
before it is returned. Ex: To check if XON/OFF protocol is being used you
would use -- if (async_stat(COM1, B_XUSE); where COM1 = 1 and
B_XUSE is defined in the COMM.H file as 0x0001.
-------------------------------------------------------------------------------
ASYNC_STRIP -- set the strip mask for incoming characters.
-------------------------------------------------------------------------------
Example:
int async_strip(int, char);
rcode = async_strip(port, mask);
Returns:
R_OK - operation was successful
R_NOPORT - the port hasn't been opened
The character passed as the mask to this function is ANDed with all incoming
data. It is automatically preset to 0x7F when using 7 data bits and 0xFF when
using 8 data bits by the async_open and async_setbpds functions.
-------------------------------------------------------------------------------
ASYNC_TX -- move a character to the transmit buffer.
-------------------------------------------------------------------------------
Example:
int async_tx(int, char);
free_space = async_tx(port, 'A');
Returns:
Number of bytes left available in the tx buffer if successful.
R_TXERR - the tx buffer was full or the port hadn't been opened
-------------------------------------------------------------------------------
ASYNC_TXFLUSH -- flush the transmit buffer.
-------------------------------------------------------------------------------
Example:
int async_txflush(int);
rcode = async_txflush(port);
Returns:
R_OK - operation was successful
R_NOPORT - the port hasn't been opened
-------------------------------------------------------------------------------
ASYNC_TXFREE -- get number of bytes of free space left in the tx buffer.
-------------------------------------------------------------------------------
Example:
int async_txfree(int);
nmbr_chars_that_can_be_txd = async_txfree(port);
Returns:
Number of bytes of free space left in the transmit buffer.
R_NOPORT - the port hasn't been opened
This value is also the return value of a call to async_tx.
-------------------------------------------------------------------------------
ASYNC_TXIMD -- put a block of data at the head of the transmit buffer.
-------------------------------------------------------------------------------
Example:
int async_tximd(int, char *, int);
tx_bytes_free = async_tximd(port, data_ptr, count);
Returns:
Number bytes left available in transmit buffer if successful.
R_TXERR - the port hasn't been opened or not enough room in tx buffer
This function moves 'count' bytes of data starting at 'data_ptr' to the head
of the transmit buffer. These bytes will be transmitted ahead of any bytes
already in the buffer and then the bytes already in the buffer will continue
to be transmitted.
-------------------------------------------------------------------------------
ASYNC_XOFFCLR -- manually clear an XOFF received condition.
-------------------------------------------------------------------------------
Example:
int async_xoffclr(int);
rcode = async_xoffclr(port);
Returns:
R_OK - operation was successful
R_BADARG - not using XON/XOFF protocol
R_NOPORT - the port hasn't been opened
Provides a means to clear an XOFF recieved condition if the sending system
fails to send an XON.
-------------------------------------------------------------------------------
ASYNC_XONANY -- allow any char received to treated as an XON if XOFF active
-------------------------------------------------------------------------------
Example:
int async_xonany(int, int);
rcode = async_xonany(port, flag);
Returns:
R_OK - operation was successful
R_BADARG - not using XON/XOFF protocol
R_NOPORT - the port hasn't been opened
Passing a non-zero value as the flag in this function causes any character
received to de-activate an XOFF received condition. A zero value as the flag
will make the protocol treat only the XON character as the XOFF clearing
character. This is included for the ^S to pause, any key to restart type
setup.
-------------------------------------------------------------------------------
ASYNC_XONOFF -- enable/disable use of XON/OFF flow control.
-------------------------------------------------------------------------------
Example:
int async_xonoff(int, int);
rcode = async_xonoff(port, flag);
Returns:
R_OK - operation was successful
R_NOPORT - the port hasn't been opened
Turns use of XOFF protocol on if flag is non-zero else disables use of XOFF.
If an XOFF is active when disabling protocol use it will be automatically
cleared and transmission will resume. If an XOFF has been sent when disabling
XOFF protocol use, an XON character is sent and then the protocol is disabled.
The XOFF protocol as implemented by these routines sends an XOFF when the
buffer is within so many bytes of being full rather than a percentage. The
number of bytes is defined as the variable XOFFCOUNT in ASYNC.H. The XON is
sent when the number of free bytes in the rx buffer is at least XONCOUNT.
These values are currently about 50 bytes different to prevent repeated sending
of XON's and XOFF's when the buffer is at the threshhold level. Another
variable defined in ASYNC.H, REPTXOFFVAL, determines how many bytes can be
received after an XOFF is sent before another XOFF is sent. Some systems
allow any character received after getting an XOFF to be interpreted as the
XON signal including another XOFF so setting REPTXOFFVAL too low will effect-
ively disable the protocol. Also some systems, RBBS, seem to be picky about
when they will accept an XOFF while other systems, PROCOMM, respond instantly.
The values chosen seem to be the most likely to work in all situations.